package com.fin.quant.app.asset.service.impl;

import cn.hutool.core.date.DateUtil;

import com.fin.quant.app.asset.service.AssetService;
import com.fin.quant.app.vo.*;
import com.fin.quant.app.vo.mapper.DividendHistoryMapperStruct;
import com.fin.quant.domain.entity.AssetEntity;
import com.fin.quant.domain.entity.TagEntity;
import com.fin.quant.domain.entity.TargetMetricsEntity;
import com.fin.quant.domain.repository.TargetMetricsRepository;
import com.fin.quant.domain.repository.TargetTagRepository;
import com.fin.quant.domain.service.AssetDaoService;
import com.fin.quant.domain.service.DividendDaoService;
import com.fin.quant.domain.vo.GetAssetsQuery;
import com.fin.quant.instra.mysql.model.Asset;
import com.fin.quant.instra.mysql.model.Dividend;
import com.fin.quant.instra.mysql.model.DividendHistory;
import com.fin.quant.rpc.common.Result;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.fin.quant.app.vo.MetricVO.convertMetricEntityToVO;

/**
 * 资产应用服务实现
 */
@Service
public class AssetServiceImpl implements AssetService {

    @Autowired
    private AssetDaoService assetDaoService;

    @Autowired
    private DividendDaoService dividendDaoService;

    @Autowired
    private TargetTagRepository targetTagRepository;

    @Autowired
    private TargetMetricsRepository targetMetricsRepository;

    @Override
    public List<AssetEntity> getAllAssets() {
        List<AssetEntity> assets = assetDaoService.getAll();
        return assets;
    }

    @Override
    public Result<AssetListResponse> getAssets(GetAssetsRequest request) {
        // TODO: 实现获取资产列表业务逻辑
        // 1. 调用领域服务查询资产数据
        // 2. 转换为VO对象
        // 3. 构建分页信息
        // 4. 返回结果

        Page<Object> page = PageHelper.startPage(request.getPage(), request.getPageSize());
        GetAssetsQuery getAssetsQuery = new GetAssetsQuery();
        getAssetsQuery.setAssetType(request.getAssetType());
        getAssetsQuery.setSector(request.getSector());
        getAssetsQuery.setAssetCode(request.getAssetCode());
        getAssetsQuery.setAssetName(request.getAssetName());
        getAssetsQuery.setMarket(request.getMarket());
        getAssetsQuery.setSortOrder(request.getSortOrder());
        List<AssetEntity> assets = assetDaoService.findAssets(getAssetsQuery);

        List<Long> assetIdList = assets.stream().map(AssetEntity::getId).collect(Collectors.toList());

        List<Dividend> dividendByAssetIdList = dividendDaoService.findDividendByAssetIdList(assetIdList);

        List<DividendHistory> dividendHisList = dividendDaoService.findDividendHisList(assetIdList);

        Map<Long, List<TagEntity>> assetTagsMap = targetTagRepository.getAssetTagsMap(assetIdList);

        Map<Long, List<TargetMetricsEntity>> assetMetricsMap = targetMetricsRepository.getAssetMetricsMap(assetIdList);

        // 按 assetId 分组
        Map<Long, Dividend> dividendByAssetIdMap = dividendByAssetIdList.stream()
                .collect(Collectors.toMap(Dividend::getAssetId, Function.identity()));

        Map<Long, List<DividendHistory>> dividendHisMap = dividendHisList.stream()
                .collect(Collectors.groupingBy(DividendHistory::getAssetId));

        AssetListResponse response = new AssetListResponse();

        List<AssetVO> assetVOList = assets.stream().map(asset -> {
            AssetVO assetVO = convertAssetToVO(asset);
            Dividend dividend = dividendByAssetIdMap.get(asset.getId());
            if (dividend != null) {
                assetVO.setCurrentPrice(dividend.getCurrentPrice().doubleValue());
                assetVO.setDividendYield(dividend.getDividendYield().doubleValue() * 100);
                assetVO.setAmountPerShare(dividend.getAmountPerShare().doubleValue());
            }

            List<TagEntity> tagEntities = assetTagsMap.get(asset.getId());
            if (CollectionUtils.isNotEmpty(tagEntities)) {
                List<TagVO> tagVOS = tagEntities.stream().map(TagVO::convertTagEntityToVO)
                        .collect(Collectors.toList());
                assetVO.setTags(tagVOS);
            }

            List<TargetMetricsEntity> targetMetricsEntities = assetMetricsMap.get(asset.getId());
            if (CollectionUtils.isNotEmpty(targetMetricsEntities)) {
                List<MetricVO> targetMetricsVOS = targetMetricsEntities.stream()
                        .map(MetricVO::convertMetricEntityToVO)
                        .collect(Collectors.toList());
                assetVO.setMetrics(targetMetricsVOS);
            }

            List<DividendHistory> dividendHistories = dividendHisMap.get(asset.getId());
            if (CollectionUtils.isNotEmpty(dividendHistories)) {
                List<DividendHistoryVO> dividendHistoryVOS = dividendHistories.stream().map(
                        dividendHistory -> DividendHistoryMapperStruct.INSTANCE.dividendHistory2VO(dividendHistory))
                        .collect(Collectors.toList());
                assetVO.setDividendHistoryList(dividendHistoryVOS);
            }

            return assetVO;
        }).collect(Collectors.toList());
        response.setAssets(assetVOList);

        PaginationVO pagination = new PaginationVO();
        pagination.setPage(request.getPage());
        pagination.setPageSize(request.getPageSize());
        pagination.setTotal(page.getTotal());
        pagination.setTotalPages(page.getPages());
        response.setPagination(pagination);
        return Result.createSuccessResult(response);
    }

    public static AssetVO convertAssetToVO(AssetEntity asset) {
        return AssetVO.convertAssetToVO(asset);
    }

    @Override
    public Result<AssetDetailResponse> getAssetDetail(Long assetId) {
        // TODO: 实现获取资产详情业务逻辑
        // 1. 调用领域服务查询资产详情
        // 2. 查询分红信息
        // 3. 查询分红历史
        // 4. 查询指标数据
        // 5. 查询标签信息
        // 6. 查询相关资产
        // 7. 组装返回结果

        AssetEntity asset = assetDaoService.findById(assetId);

        AssetDetailResponse response = new AssetDetailResponse();
        AssetVO assetVO = convertAssetToVO(asset);
        response.setAsset(assetVO);

        Dividend dividend = dividendDaoService.findDividendByAssetId(assetId);
        if (dividend != null) {
            DividendVO dividendVO = convertDividendToVO(dividend);
            response.setDividend(dividendVO);
        }

        return Result.createSuccessResult(response);
    }

    private static DividendVO convertDividendToVO(Dividend dividend) {
        DividendVO dividendVO = new DividendVO();
        dividendVO.setId(dividend.getId());
        dividendVO.setAssetId(dividend.getAssetId());
        dividendVO.setFiscalYear(dividend.getFiscalYear());
        dividendVO.setCurrentPrice(dividend.getCurrentPrice().doubleValue());
        dividendVO.setDividendYield(dividend.getDividendYield().doubleValue());
        dividendVO.setAnnualDividend(dividend.getAnnualDividend().doubleValue());
        dividendVO.setAmountPerShare(dividend.getAmountPerShare().doubleValue());
        if (dividend.getExDividendDate() != null) {
            dividendVO.setExDividendDate(DateUtil.format(dividend.getExDividendDate(), "yyyy-MM-dd"));
        }
        if (dividend.getPaymentDate() != null) {
            dividendVO.setPaymentDate(DateUtil.format(dividend.getPaymentDate(), "yyyy-MM-dd"));
        }

        dividendVO.setFrequency(dividend.getFrequency());
        dividendVO.setGrowthRate(dividend.getGrowthRate().doubleValue());
        dividendVO.setPayoutRatio(dividend.getPayoutRatio().doubleValue());
        return dividendVO;
    }

    @Override
    public Result<AssetListResponse> searchAssets(SearchAssetsRequest request) {
        // TODO: 实现搜索资产业务逻辑
        // 1. 调用领域服务搜索资产
        // 2. 转换为VO对象
        // 3. 构建分页信息
        // 4. 返回结果

        AssetListResponse response = new AssetListResponse();
        return Result.createSuccessResult(response);
    }

    @Override
    public Result<AssetListResponse> applyFilter(ApplyFilterRequest request) {
        // TODO: 实现应用筛选业务逻辑
        // 1. 调用领域服务应用筛选条件
        // 2. 转换为VO对象
        // 3. 构建分页信息
        // 4. 返回结果

        AssetListResponse response = new AssetListResponse();
        return Result.createSuccessResult(response);
    }
}
